package com.cy.store.controller;

import com.cy.store.controller.ex.*;
import com.cy.store.entity.User;
import com.cy.store.service.IUserService;
import com.cy.store.service.ex.InsertException;
import com.cy.store.service.ex.UsernameDuplicatedException;
import com.cy.store.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author: AngJie
 * @create: 2022-02-06 00:58
 **/
// @Controller
@RestController
@RequestMapping("users")
public class UserController extends BaseController {

    @Autowired
    private IUserService userService;


    /*
     * 接收数据方式：请求处理方法的参数列表设置为pojo类型来接收前端的数据。
     *   springboot会将前端的url地址中的参数名和pojo类的属性名进行比较，如果名称相同，则注入到pojo类中
     * */
    @RequestMapping("regist")
    public JsonResult regist(User user) {
        //创建响应对象
        JsonResult result = new JsonResult<>();
        userService.regist(user);
        result.setState(OK);
        result.setMessage("注册成功");
        return result;
    }

    /*
     * 接收数据方式：请求的处理方法的参数列表设置为非pojo类型
     *   spirngboot会自动将请求的参数名和方法的参数名直接进行比较，如果相同则注入
     * */
    @RequestMapping("login")
    public JsonResult<User> login(User user,
                                  HttpSession httpSession) {
        //创建响应对象
        JsonResult<User> result = new JsonResult<>();
        User login = userService.login(user);
        //将用户名和uid封装到session对象中(这个是全局的session对象)
        httpSession.setAttribute("uid", login.getUid());
        httpSession.setAttribute("username", login.getUsername());

        result.setState(OK);
        result.setMessage("登录成功");
        result.setData(login);

        return result;
    }

    /**
     * 修改密码
     *
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @RequestMapping("change_pw")
    public JsonResult changePasssword(String oldPassword,
                                      String newPassword,
                                      HttpSession session) {
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        userService.changePassword(uid, oldPassword, newPassword);
        return new JsonResult(OK);
    }

    @RequestMapping("get_by_uid")
    public JsonResult<User> getByUid(HttpSession session) {
        Integer uid = getUidFromSession(session);
        User result = userService.getByUid(uid);
        return new JsonResult<>(OK, result);

    }

    @RequestMapping("change_info")
    public JsonResult changeInfo(User user, HttpSession session) {
        Integer uid = getUidFromSession(session);
        userService.changeInfo(uid, user);
        return new JsonResult(OK);
    }

    //设置上传文件最大值
    public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024;

    //设置上传文件的类型
    public static final List<String> AVATAR_TYPE = new ArrayList<>();

    static {
        AVATAR_TYPE.add("image/jpeg");
        AVATAR_TYPE.add("image/png");
        AVATAR_TYPE.add("image/bmp");
        AVATAR_TYPE.add("image/gif");
    }

    /**
     * MultipartFile接口是SpringMVC提供的一个接口，这个接口为我们包装了获取文件的数据，
     * springboot整合了SpringMVC，只需在请求方法参数列表声明一个类型为MultipartFile的参数即可，
     * springboot会自动将文件数据封装给这个参数
     *
     * @param session
     * @param file
     * @return
     */
    // 如果不配置method，
    // 则以任何请求形式都可以访问到
    @RequestMapping("change_avatar")
    public JsonResult<String> changeAvatar(HttpSession session,
                                           @RequestParam("file") MultipartFile file) {
        //判断文件是否为空
        if (file.isEmpty()) {
            throw new FileEmptyException("文件为空");
        }
        //判断文件大小
        if (file.getSize() > AVATAR_MAX_SIZE) {
            throw new FileSizexception("文件大小超出限制");
        }
        //判断文件类型
        String fileType = file.getContentType();
        //如果集合包含则为true，否则为false
        if (!AVATAR_TYPE.contains(fileType)) {
            throw new FileTypeException("文件类型不支持");
        }
        //上传的文件 .../upload/文件.xxx
        String parent = session.getServletContext().getRealPath("upload");
        //springboot每次启动的项目路径是随机生成的
        System.out.println("parent = " + parent);
        //File对象指向这个路径,File是否存在
        File dir = new File(parent);
        if (!dir.exists()) {
            //创建当前目录
            dir.mkdirs();
        }
        //获取到这个文件名称，UUID工具将生成一个新的字符串作为文件名
        //getOriginalFilename()返回的是文件名加后缀，不包括文件路径
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //将文件后缀与UUID随机生成的值拼接作为新文件名
        String filename = UUID.randomUUID().toString().toUpperCase() + suffix;

        //创建一个同名空文件再将数据写入到这个空文件
        File dest = new File(dir, filename);
        try {
            file.transferTo(dest);
        } catch (FileStateException e) {
            throw new FileUploadIOException("文件状态异常");
        } catch (IOException e) {
            throw new FileUploadIOException("文件读写异常");
        }

        Integer uid = getUidFromSession(session);
        //返回头像的路径 项目路径下的/upload/test.xxx
        String avatar = "/upload/" + filename;
        userService.changeAvatar(uid, avatar);

        //返回用户头像的路径给前端，将来用于头像展示使用
        return new JsonResult<String>(OK, avatar);
    }


    // @RequestMapping("regist")
    // public JsonResult<Object> regist(User user){
    //     //创建响应对象
    //     JsonResult<Object> result = new JsonResult<>();
    //     try {
    //         userService.regist(user);
    //         result.setState(200);
    //         result.setMessage("注册成功");
    //     } catch (UsernameDuplicatedException e) {
    //         result.setState(4000);
    //         result.setMessage(e.getMessage());
    //     } catch (InsertException e) {
    //         result.setState(5000);
    //         result.setMessage(e.getMessage());
    //     }finally {
    //         return result;
    //     }
    // }
}
